package utils

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"os"
)

// 保存生成的公钥和密钥
func SaveRsaSignKey(bits int) error {

	private, err := rsa.GenerateKey(rand.Reader, bits)
	fmt.Println(private)
	fmt.Println(err)

	if err != nil {
		return err
	}

	publicKey := private.PublicKey

	//使用 x509 标准进行编码  AsN,1 编码字符串
	x509_Private := x509.MarshalPKCS1PrivateKey(private)
	// 使用x509标准对公钥进行编码， AsN.1编码字符串
	x509_public := x509.MarshalPKCS1PublicKey(&publicKey)

	fmt.Println(x509_Private)
	fmt.Println(x509_public)
	// 对私钥进行封装 block 结构数据
	block_private := pem.Block{Type: "private key", Bytes: x509_Private}
	// 对公钥进行封装 block 结构数据
	block_public := pem.Block{Type: "public key", Bytes: x509_public}

	// 存放私钥的文件
	privateFile, err_pri := os.Create("privateKey.pem")
	if err_pri != nil {
		return err_pri
	}
	defer privateFile.Close()
	pem.Encode(privateFile, &block_private)
	// 存放公钥的文件
	publicFile, err_pub := os.Create("publicKey.pem")
	if err_pub != nil {
		return err_pub
	}
	defer publicFile.Close()
	pem.Encode(publicFile, &block_public)
	return nil
}

// 获取公钥
func GetPublicKey(file_path string) (*rsa.PublicKey, error) {
	// 打开文件
	file, err := os.Open(file_path)
	if err != nil {
		return &rsa.PublicKey{}, err
	}

	file_info, err_info := file.Stat()
	if err_info != nil {
		return &rsa.PublicKey{}, err_info
	}
	// 读取文件
	key_bytes := make([]byte, file_info.Size())
	//读取内容到容器里面
	file.Read(key_bytes)

	// pem 解码
	block, _ := pem.Decode(key_bytes)

	//x509解码
	public_Key, err_pb := x509.ParsePKCS1PublicKey(block.Bytes)
	if err_pb != nil {
		return &rsa.PublicKey{}, err_pb
	}
	//fmt.Println(public_Key)

	return public_Key, nil
}

// 获取私钥
func GetPrivateKey(file_path string) (*rsa.PrivateKey, error) {
	// 读文件
	file, err := os.Open(file_path)
	if err != nil {
		return &rsa.PrivateKey{}, err
	}

	file_info, err_info := file.Stat()
	if err_info != nil {
		return &rsa.PrivateKey{}, err_info
	}
	// 读取文件
	key_bytes := make([]byte, file_info.Size())
	//读取内容到容器里面
	file.Read(key_bytes)

	// pem 解码
	block, _ := pem.Decode(key_bytes)

	//x509解码
	privateKey, err_pb := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err_pb != nil {
		return &rsa.PrivateKey{}, err_pb
	}

	return privateKey, nil
}

// 数字签名  ， 使用的是私钥
func RsaGetString(file_path string, src string) ([]byte, error) {
	//拿到私钥
	privateKey, err := GetPrivateKey(file_path)
	if err != nil {
		return []byte{}, err
	}

	sha_new := sha256.New()
	src_byte := []byte(src)
	sha_new.Write(src_byte)
	sha_bytes := sha_new.Sum(nil)

	// 签名
	sign, err_sign := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, sha_bytes)
	if err_sign != nil {
		return []byte{}, err_sign
	}

	return sign, nil
}

// 验证签名， 使用的是公钥
func RsaVarifySign(sign []byte, file_path, src string) (bool, error) {
	publicKey, err := GetPublicKey(file_path)
	if err != nil {
		return false, err
	}

	sha_new := sha256.New()
	src_byte := []byte(src)
	sha_new.Write(src_byte)
	sha_bytes := sha_new.Sum(nil)

	//验证签名
	err_varify := rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, sha_bytes, sign)
	if err_varify != nil { // 验证失败
		return false, nil
	}

	return true, nil
}
